/**
 * Author : Fengyuan(Franklin) Zhang
 * Date : 2019/3/4
 * Description : Route for all request
 */
var request = require('request');
var Setting = require('../setting');
var MDLParser = require('../utils/mdlParser');
var ModelServiceCtrl = require('../controls/model_service');
var DataCtrl = require('../controls/data');
var multer  = require('multer');

module.exports = function(app)
{
  //! View
  app.route('/')
    .get(function(req, res, next){
      return res.render('model_services');
    });
  
  app.route('/modelser/:id')
    .get(function(req, res, next){
      if(req.query.ac == 'run'){
        var inputs = JSON.parse(req.query.inputdata);
        var inputs_t = [];
        var pid = req.params.id;

        for(var i = 0; i < inputs.length; i++){
          inputs_t.push({
              "StateName" : inputs[i].StateName,
              "Event" : inputs[i].Event,
              "Url" : inputs[i].DataId,
              "Tag" : inputs[i].Tag
          })
        }

        var taskinfo = {
          inputs : JSON.stringify(inputs_t),
          username : "[Unknown]",
          pid : pid
        }

        request.post('http://' + Setting.binding.ip + ':' + Setting.binding.port.toString() + '/task', {form : taskinfo}, function (err, response, body) {
          if(err){
            return res.end(JSON.stringify({
              result : 'err',
              code : -1,
              message : err.message,
              data : ''
            }));
          }
          var resJson = JSON.parse(body);
          if(resJson.result == 'suc'){
            return res.end(JSON.stringify({
              result : 'suc',
              code : 1,
              message : '',
              data : resJson.data
            }));
          }
          else{
            return res.end(JSON.stringify({
              result : 'err',
              code : -2,
              message : 'Error in getting model',
              data : ''
            }));
          }
        });
      }
      else{
        return res.render('model_info', {
          msid : req.params.id
        });
      }
    });
  
  app.route('/modelser/preparation/:id')
    .get(function(req, res, next){
      DataCtrl.refreshRecommendDXServer(function(err, result){
        if(err){
          return res.render('error', {
            message : 'Can not find DX server!',
            error : {
              status : 'Please try later...',
              stack : ''
            }
          });
        }
        else if(result == true){
          return res.render('task_creation', {
            msid : req.params.id
          });
        }
        else{
          return res.render('error', {
            message : 'Can not find DX server!',
            error : {
              status : 'Please try later...',
              stack : ''
            }
          });
        }
      });
    });

  app.route('/task/:id')
    .get(function(req, res, next){
      var tid = req.params.id;
      res.render('task_info',{
        tid : tid
      });
    })


  ////////////////////////////////////////////////////////////////
  //! API
  app.route('/modelser/json/all')
    .get(function(req, res, next){
      ModelServiceCtrl.refreshModelServicesData(function(err, result){
        if(err){
          return res.end(JSON.stringify({
            result : 'err',
            code : -1,
            message : err.message,
            data : ''
          }));
        }
        return res.end(JSON.stringify({
          result : 'suc',
          code : 1,
          message : '',
          data : global.data_cache
        }));
      });
    });

  app.route('/modelser/json/:id')
    .get(function(req, res, next){
      //! get model service info by pid
      var pid = req.params.id;
      ModelServiceCtrl.getModelServiceByPID(pid, function (err, ms) {
        if(err){
          return res.end(JSON.stringify({
            result : 'err',
            code : -1,
            message : '',
            data : ''
          }));
        }
        return res.end(JSON.stringify({
          result : 'suc',
          code : 1,
          message : '',
          data : ms
        }));
      });
    });

  app.route('/modelser/inputdata/json/:id')
    .get(function(req, res, next){
      //! get model service input data by pid
      var pid = req.params.id;
      ModelServiceCtrl.getModelServiceByPID(pid, function (err, ms) {
        if(err){
          return res.end(JSON.stringify({
            result : 'err',
            code : -1,
            message : err.message,
            data : ''
          }));
        }
        if(ms == null){
          return res.end(JSON.stringify({
            result : 'err',
            code : 0,
            message : 'No such model service',
            data : null
          }));
        }
        var mdl = new MDLParser();
        mdl.loadFromJSONStream(ms.ms_xml);
        var statesGroup = mdl.Behavior.StateGroup;
        statesGroup.States.forEach(state => {
          state['$'] = {
            id : state.id,
            name : state.name,
            type : state.type,
            description : state.description
          }
          delete state.id;
          delete state.name;
          delete state.type;
          delete state.description;
          state.Events.forEach(event => {
            var optional = 0;
            if(event.optional){
              optional = 1;
            }
            event['$'] = {
              name : event.name,
              type : event.type,
              optional : optional,
              description : event.description
            }
            delete event.name;
            delete event.type;
            delete event.optional;
            delete event.description;
            if(event["ParametersType"] == "ResponseParameter"){
              event["ResponseParameter"] = {
                $ : {
                  datasetReference : event["dataReference"],
                  description : event["dataDescription"]
                }
              };
            }
            else if(event["ParametersType"] == "DispatchParameter"){
              event["DispatchParameter"] = {
                $ : {
                  datasetReference : event["dataReference"],
                  description : event["dataDescription"]
                }
              };
            }
            delete event.ParametersType;
            delete event.dataReference;
            delete event.dataDescription;
          });
          state.Event = state.Events;
          delete state.Events;
        });

        statesGroup['Permission'] = ms.ms_permission;
        statesGroup['Params'] = {
          ProcessParameters:[],
          ControlParameters:[]
        }
        
        return res.end(JSON.stringify({
          result : 'suc',
          code : 1,
          message : '',
          data : statesGroup
        }));
      });
    });

  var upload = multer({ dest: 'uploads/' });
  app.route('/data', upload.single('file'))
    .post(function(req, res, next){
      if(req.query.type == 'file'){
        DataCtrl.postData(req, function(err, data){
          if(err){
            return res.end(JSON.stringify({
              result : 'err',
              code : -1,
              message : err.message,
              data : ''
            }));
          }
          
          return res.end(JSON.stringify({
            result : 'suc',
            code : 1,
            message : '',
            data : data
          }));
        });
      }
    });

  app.route('/task/json/:id')
    .get(function(req, res, next){
      var tid = req.params.id;
      var url = 'http://' + Setting.binding.ip + ':' + Setting.binding.port.toString() + '/task/' + tid;
      request.get(url, function (err, respones, body) {
          if(err){
            return res.end(JSON.stringify({
              result : 'err',
              code : -1,
              message : err.message,
              data : ''
            }));
          }
          body = JSON.parse(body);
          if(body.result == 'err'){
            return res.end(JSON.stringify({
              result : 'err',
              code : -2,
              message : body.message,
              data : ''
            }));
          }
          return res.end(JSON.stringify({
            result : 'suc',
            code : 1,
            message : '',
            data : body['data']
          }));
      });
    });
}
